package com.spzx.rabbit.config;


import com.alibaba.fastjson2.JSON;
import com.spzx.rabbit.entity.GuiguCorrelationData;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

@Component
public class RabbitInitConfigImpl implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback{

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    RedisTemplate redisTemplate;


    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String errMsg) {
        GuiguCorrelationData guiguCorrelationData = (GuiguCorrelationData)correlationData;
        System.out.println(guiguCorrelationData);
        // 发送失败后可以重试
        if(!ack){
            retry(guiguCorrelationData);
        }
        System.out.println("发送确认");
    }

    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        String correlationId = returnedMessage.getMessage().getMessageProperties().getCorrelationId();
        String redisKey = returnedMessage.getMessage().getMessageProperties().getHeader("spring_returned_message_correlation");
        GuiguCorrelationData correlationData = JSON.parseObject((String)redisTemplate.opsForValue().get(redisKey),GuiguCorrelationData.class);
        boolean delay = correlationData.isDelay();
        if(!delay){
            retry(correlationData);
        }
        System.out.println("投递确认");
    }


    private void retry(GuiguCorrelationData guiguCorrelationData) {
        System.out.println("重试消息");
        int retryCount = guiguCorrelationData.getRetryCount();
        if(retryCount>0){
            System.out.println("还有重试机会:"+retryCount+"，重新尝试发送");
            retryCount--;
            guiguCorrelationData.setRetryCount(retryCount);
            // 更新redis中的用来投递失败的缓存data
            redisTemplate.opsForValue().set(guiguCorrelationData.getId(), JSON.toJSONString(guiguCorrelationData), 10, TimeUnit.MINUTES);
            rabbitTemplate.convertAndSend(guiguCorrelationData.getExchange(),guiguCorrelationData.getRoutingKey(),guiguCorrelationData.getMessage(),guiguCorrelationData);
        }else {
            System.out.println("重试机会用尽，放弃尝试发送");
        }
    }



}
